import os
from constants import *
from vm_parser import Parser
from vm_code_writer import CodeWriter
import argparse
import os.path
import glob
from functional import pseq, seq


def translate(file, code_writer):
    srcfile, _ = os.path.splitext(os.path.basename(file))
    with Parser(file) as parser:
        while parser.advance() != "":
            if parser.command_type() == C_ARITHMETIC:
                code_writer.writeArithmetic(parser.arg1())
            elif parser.command_type() == C_PUSH or parser.command_type() == C_POP:
                codeWriter.writePushPop(srcfile,
                                        parser.command_type(), parser.arg1(), parser.arg2())
            elif parser.command_type() == C_LABEL:
                codeWriter.writeLabel(parser.arg1())
            elif parser.command_type() == C_IF:
                codeWriter.writeIf(parser.arg1())
            elif parser.command_type() == C_GOTO:
                codeWriter.writeGoto(parser.arg1())
            elif parser.command_type() == C_FUNCTION:
                codeWriter.writeFunction(parser.arg1(), parser.arg2())
            elif parser.command_type() == C_RETURN:
                codeWriter.writeReturn()
            elif parser.command_type() == C_CALL:
                codeWriter.writeCall(parser.arg1(), parser.arg2())
    return True


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('files', nargs='*', type=str, help='vm files')

    args = parser.parse_args()
    files = seq(args.files).filter(lambda f: f.endswith('.vm')).to_list()
    paths = seq(args.files).filter(lambda f: os.path.isdir(f)).to_list()
    if len(files) > 1:
        # 对每个文件生成单独编译文件
        executor = seq(files)
        executor.map(lambda file: translate(
            file, CodeWriter(file.strip(".vm") + ".asm"))).to_list()

    # 对文件夹下所有文件生成一个编译文件
    for path in paths:
        files = seq(glob.glob("%s/*" % path)
                    ).filter(lambda f: f.endswith('.vm')).to_list()
        destfile = os.path.split(path.strip('/'))[-1]
        destfile = os.path.join(path, destfile + ".asm")
        codeWriter = CodeWriter(destfile)
        executor = seq(files)
        executor.map(lambda file: translate(file, codeWriter)).to_list()
        codeWriter.Close()
